package models;

import java.awt.image.BufferedImage;
import java.util.Date;
import java.util.List;
import java.util.Set;

import javax.imageio.ImageIO;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import play.data.validation.Check;
import play.data.validation.CheckWith;
import play.data.validation.Required;
import play.db.jpa.Blob;
import play.db.jpa.JPABase;
import play.db.jpa.Model;
import controllers.Application;

/**
 * Classe que representa a entidade Imovel
 * @author Marcos
 */

@Entity
public class Imovel extends Model{

	@Required(message="validacao.requerido")
	public String descricao;
	public double valor;
	public int quartos;
	public int suites;
	public int vagasGaragem;
	public double iptu;
	public double condominio;
	public String cep;
	public double largura;
	public double comprimento;
	public double areaTotal;
	
	@Temporal(TemporalType.TIMESTAMP)
	public Date dataPublicacao;
	
	@CheckWith(value=ImagemCheck.class,message="validacao.imagemcheck1")
	public Blob imagem1;
	@CheckWith(value=ImagemCheck.class,message="validacao.imagemcheck2")
	public Blob imagem2;
	@CheckWith(value=ImagemCheck.class,message="validacao.imagemcheck3")
	public Blob imagem3;
	
	@ManyToOne
    public Usuario usuario;
	
	@Required(message="validacao.requerido")
	@ManyToOne
	public TipoImovel tipoImovel;
	
	@OneToMany(mappedBy="imovel",cascade=CascadeType.ALL)
	public List<Anuncio> anuncio;
	
	@Required(message="validacao.requerido")

	@ManyToOne
	public Transacao transacao;
	
	@ManyToOne
	public Bairro bairro;
	
	@ManyToMany(cascade=CascadeType.PERSIST)
	public List<Caracteristica> caracteristicas;
	
	@OneToMany(mappedBy="imovel",cascade=CascadeType.ALL)
	public List<Comentario> comentarios;
	
	@ManyToMany(cascade=CascadeType.PERSIST)
	public Set<Usuario> usuarios;
	
	public boolean status;
	
	public boolean pago;
	
	public boolean publicado;
	
	@Override
    public <T extends JPABase> T save() {
    	if (imagem1 != null && imagem1.exists()){
    		play.libs.Images.resize(imagem1.getFile(), imagem1.getFile(), 160, 160);
    	}
    	if (imagem2 != null && imagem2.exists()){
    		play.libs.Images.resize(imagem2.getFile(), imagem2.getFile(), 160, 160);
    	}
    	if (imagem3 != null && imagem3.exists()){
    		play.libs.Images.resize(imagem3.getFile(), imagem3.getFile(), 160, 160);
    	}
    	return super.save();
    }
	
	/**
     * Remove o arquivo de imagem do contato durante a exclusao da entrada no banco de dados
     */
	@Override
	public <T extends JPABase> T delete() {
		if (imagem1.exists()) {
			imagem1.getFile().delete();
		}
		if (imagem2.exists()) {
			imagem2.getFile().delete();
		}
		if (imagem3.exists()) {
			imagem3.getFile().delete();
		}
		return super.delete();
	}
	
	/**
     * Metodo vindouro da interface Comparable. Serve para ordenar uma colecao de objetos.
     * Ordena os Contatos pela data de inclusao, decrescente.
     * @see Application#index()
     */
	public int compareTo(Object o) {
		Imovel i = (Imovel) o; 
		if (this.id >= i.id)
			return -1;
		else if (this.id <= i.id)
			return 1;
		else
			return 0;
	}

	static class ImagemCheck extends Check {
		
		@Override
		public boolean isSatisfied(Object validatedObject, Object value) {
			Blob b = (Blob) value;
			// Se o objeto for nulo, entao nao precisa validar, porque nao tem arquivo
			if (b == null || b.get()==null)
				return true;
			
			// Se uma excecao for lancada entao arquivo nao eh uma imagem
			try {
				BufferedImage br = ImageIO.read(b.getFile());
				if (br==null)
					b.getFile().delete();
				return br!=null;
			} catch (Exception e) {
				b.getFile().delete();
				return false;
			}
		}   
    }
	
}
